home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / dflat_r_.arc / MENUBAR.C < prev    next >
Text File  |  1991-10-02  |  11KB  |  390 lines

  1. /* ---------------- menubar.c -------------- */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <dos.h>
  8. #include "dflat.h"
  9.  
  10. static void reset_menubar(WINDOW);
  11. static int TestGlobalKeys(WINDOW, PARAM, PARAM);
  12.  
  13. static struct {
  14.     int x1, x2;        /* position in menu bar */
  15.     char sc;        /* shortcut key value   */
  16. } menu[10];
  17. static int mctr;
  18.  
  19. MBAR *ActiveMenuBar;
  20. static MENU *ActiveMenu;
  21. WINDOW MenuBarWnd;
  22.  
  23. static WINDOW mwnd;
  24. static int Selecting;
  25.  
  26. static WINDOW Cascaders[MAXCASCADES];
  27. static int casc;
  28.  
  29. int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  30. {
  31.     int offset = 3, wd, offset1, i, j, mx, my;
  32.     MENU *mnu;
  33.     int rtn;
  34.     static int AltDown = FALSE;
  35.  
  36.     switch (msg)    {
  37.         case CREATE_WINDOW:
  38.             MenuBarWnd = wnd;
  39.             reset_menubar(wnd);
  40.             break;
  41.         case SETFOCUS:
  42.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  43.             if ((int) p1)    {
  44.                 if (ActiveMenuBar->ActiveSelection == -1)
  45.                     ActiveMenuBar->ActiveSelection = 0;
  46.                 if (inFocus == wnd)
  47.                     SendMessage(wnd, PAINT, 0, 0);
  48.             }
  49.             else    {
  50.                 SendMessage(wnd, PAINT, 0, 0);
  51. #ifdef INCLUDE_STATUSBAR
  52.                 SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  53. #endif
  54.             }
  55.             return rtn;
  56.         case COMMAND:
  57.             if (isCascadedCommand(ActiveMenuBar, (int)p1))    {
  58.                 /* find the cascaded menu based on command id in p1 */
  59.                 mnu = ActiveMenu+mctr;
  60.                 while (mnu->Title != (void *)-1)    {
  61.                     if (mnu->CascadeId == (int) p1)    {
  62.                         if (casc < MAXCASCADES)    {
  63.                             Cascaders[casc++] = mwnd;
  64.                             SendMessage(wnd, SELECTION,
  65.                                 (PARAM)(mnu-ActiveMenu), TRUE);
  66.                         }
  67.                         break;
  68.                     }
  69.                     mnu++;
  70.                 }
  71.             }
  72.             else     {
  73.                 if (mwnd != NULLWND)
  74.                     SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  75.                 SetPrevFocus(wnd);
  76.                 PostMessage(GetParent(wnd), msg, p1, p2);
  77.             }
  78.             return TRUE;
  79.         case BUILDMENU:
  80.             reset_menubar(wnd);
  81.             mctr = 0;
  82.             ActiveMenuBar = (MBAR *) p1;
  83.             ActiveMenu = ActiveMenuBar->PullDown;
  84.             while (ActiveMenu->Title != NULL)    {
  85.                 char *cp;
  86.                 if (strlen(GetText(wnd)+offset) < strlen(ActiveMenu->Title)+3)
  87.                     break;
  88.                 GetText(wnd) = realloc(GetText(wnd), strlen(GetText(wnd))+5);
  89.                 memmove(GetText(wnd) + offset+4, GetText(wnd) + offset,
  90.                         strlen(GetText(wnd))-offset+1);
  91.                 CopyCommand(GetText(wnd)+offset, ActiveMenu->Title, FALSE,
  92.                         wnd->WindowColors [STD_COLOR] [BG]);
  93.                 menu[mctr].x1 = offset;
  94.                 offset += strlen(ActiveMenu->Title) + (3+MSPACE);
  95.                 menu[mctr].x2 = offset-MSPACE;
  96.                 cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
  97.                 if (cp)
  98.                     menu[mctr].sc = tolower(*(cp+1));
  99.                 mctr++;
  100.                 ActiveMenu++;
  101.             }
  102.             ActiveMenu = ActiveMenuBar->PullDown;
  103.             break;
  104.         case PAINT:    
  105.             if (!isVisible(wnd) || GetText(wnd) == NULL)
  106.                 break;
  107.  
  108. #ifdef INCLUDE_STATUSBAR
  109.             if (wnd == inFocus)
  110.                 SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  111. #endif
  112.             SetStandardColor(wnd);
  113.             ClearAttribute(wnd, NOCLIP);
  114.  
  115.             clipline(wnd, 0, GetText(wnd));
  116.             wputs(wnd, GetText(wnd), 0, 0);
  117.  
  118.             AddAttribute(wnd, NOCLIP);
  119.             if (ActiveMenuBar->ActiveSelection != -1 &&
  120.                     (wnd == inFocus || mwnd != NULLWND))    {
  121.                 char *sel;
  122.                 char *cp;
  123.                 if ((sel = malloc(200)) != NULL)    {
  124.                     offset = menu[ActiveMenuBar->ActiveSelection].x1;
  125.                     offset1 = menu[ActiveMenuBar->ActiveSelection].x2;
  126.                     GetText(wnd)[offset1] = '\0';
  127.                     SetReverseColor(wnd);
  128.                     memset(sel, '\0', 200);
  129.                     strcpy(sel, GetText(wnd)+offset);
  130.                     cp = strchr(sel, CHANGECOLOR);
  131.                     if (cp != NULL)
  132.                         *(cp + 2) = background | 0x80;
  133.                     wputs(wnd, sel, offset-ActiveMenuBar->ActiveSelection*4, 0);
  134.                     GetText(wnd)[offset1] = ' ';
  135. #ifdef INCLUDE_STATUSBAR
  136.                     if (!Selecting && mwnd == NULLWND && wnd == inFocus)    {
  137.                         char *st = ActiveMenu[ActiveMenuBar->ActiveSelection].StatusText;
  138.                         if (st != NULL)
  139.                             SendMessage(GetParent(wnd), ADDSTATUS, (PARAM)st, 0);
  140.                     }
  141. #endif
  142.                     free(sel);
  143.                 }
  144.             }
  145.             return FALSE;
  146.         case SHIFT_CHANGED:
  147.             if (mwnd == NULLWND)    {
  148.                 if ((int)p1 & ALTKEY)
  149.                     AltDown = TRUE;
  150.                 else if (AltDown)
  151.                     SendMessage(wnd, KEYBOARD,
  152.                         wnd == inFocus ? ESC : F10, 0);
  153.             }
  154.             return TRUE;
  155.         case KEYBOARD:
  156.             AltDown = FALSE;
  157.             if (mwnd == NULLWND)    {
  158.                 /* ----- search for menu bar shortcut keys ---- */
  159.                 int c = tolower((int)p1);
  160.                 int a = AltConvert((int)p1);
  161.                 for (j = 0; j < mctr; j++)    {
  162.                     if ((inFocus == wnd && menu[j].sc == c) ||
  163.                             (a && menu[j].sc == a))    {
  164.                         if (inFocus != wnd)
  165.                             SendMessage(wnd, SETFOCUS, TRUE, 0);
  166.                         SendMessage(wnd, SELECTION, j, 0);
  167.                         return FALSE;
  168.                     }
  169.                 }
  170.             }
  171.             /* -------- search for accelerator keys -------- */
  172.             mnu = ActiveMenu;
  173.             while (mnu->Title != NULL)    {
  174.                 struct PopDown *pd = mnu->Selections;
  175.                 if (mnu->PrepMenu)
  176.                     (*(mnu->PrepMenu))(GetParent(wnd), mnu);
  177.                 while (pd->SelectionTitle != NULL)    {
  178.                     if (pd->Accelerator == (int) p1)    {
  179.                         if (pd->Attrib & INACTIVE)
  180.                             beep();
  181.                         else    {
  182.                             if (GetClass(inFocus) == MENUBAR)
  183.                                 SetPrevFocus(inFocus);
  184.                             PostMessage(GetParent(wnd),
  185.                                 COMMAND, pd->ActionId, 0);
  186.                         }
  187.                         return TRUE;
  188.                     }
  189.                     pd++;
  190.                 }
  191.                 mnu++;
  192.             }
  193.             if (TestGlobalKeys(wnd, p1, p2))
  194.                 return TRUE;
  195.  
  196.             switch ((int)p1)    {
  197. #ifdef INCLUDE_HELP
  198.                 case F1:
  199.                   if (ActiveMenu != NULL &&
  200.                       (mwnd == NULLWND ||
  201.                         (ActiveMenu+ActiveMenuBar->ActiveSelection)->
  202.                             Selections[0].SelectionTitle == NULL)) {
  203.                         DisplayHelp(wnd, (ActiveMenu+ActiveMenuBar->ActiveSelection)->Title+1);
  204.                         return TRUE;
  205.                     }
  206.                     break;
  207. #endif
  208.                 case '\r':
  209.                     if (mwnd == NULLWND && ActiveMenuBar->ActiveSelection != -1)
  210.                         SendMessage(wnd, SELECTION, ActiveMenuBar->ActiveSelection, 0);
  211.                     break;
  212.                 case ESC:
  213.                     if (inFocus == wnd)    {
  214.                         ActiveMenuBar->ActiveSelection = -1;
  215.                         SetPrevFocus(wnd);
  216.                         SendMessage(wnd, PAINT, 0, 0);
  217.                     }
  218.                     break;
  219.                 case FWD:
  220.                     ActiveMenuBar->ActiveSelection++;
  221.                     if (ActiveMenuBar->ActiveSelection == mctr)
  222.                         ActiveMenuBar->ActiveSelection = 0;
  223.                     if (mwnd != NULLWND)
  224.                         SendMessage(wnd, SELECTION, ActiveMenuBar->ActiveSelection, 0);
  225.                     else 
  226.                         SendMessage(wnd, PAINT, 0, 0);
  227.                     break;
  228.                 case BS:
  229.                     if (ActiveMenuBar->ActiveSelection == 0)
  230.                         ActiveMenuBar->ActiveSelection = mctr;
  231.                     --ActiveMenuBar->ActiveSelection;
  232.                     if (mwnd != NULLWND)
  233.                         SendMessage(wnd, SELECTION, ActiveMenuBar->ActiveSelection, 0);
  234.                     else 
  235.                         SendMessage(wnd, PAINT, 0, 0);
  236.                     break;
  237.                 default:
  238.                     break;
  239.             }
  240.             return FALSE;
  241.         case LEFT_BUTTON:
  242.             i = BarSelection((int) p1 - GetLeft(wnd));
  243.             if (i < mctr)
  244.                 if (i != ActiveMenuBar->ActiveSelection || mwnd == NULLWND)
  245.                     SendMessage(wnd, SELECTION, i, 0);
  246.             return TRUE;
  247.         case SELECTION:
  248.             Selecting = TRUE;
  249.             mnu = ActiveMenu+(int)p1;
  250.             if (mnu->PrepMenu != NULL)
  251.                 (*(mnu->PrepMenu))(GetParent(wnd), mnu);
  252.             wd = MenuWidth(mnu->Selections);
  253.             if (p2)    {
  254.                 mx = GetLeft(inFocus) +    WindowWidth(inFocus) - 1;
  255.                 my = GetTop(inFocus) + inFocus->selection;
  256.             }
  257.             else    {
  258.                 if (mwnd != NULLWND)
  259.                     SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  260.                 ActiveMenuBar->ActiveSelection = (int) p1;
  261.                 offset = menu[ActiveMenuBar->ActiveSelection].x1 -
  262.                             4 * ActiveMenuBar->ActiveSelection;
  263.                 if (offset > WindowWidth(wnd)-wd)
  264.                     offset = WindowWidth(wnd)-wd;
  265.                 mx = GetLeft(wnd)+offset;
  266.                 my = GetTop(wnd)+1;
  267.             }
  268.             mwnd = CreateWindow(POPDOWNMENU, NULL,
  269.                         mx, my,
  270.                         MenuHeight(mnu->Selections),
  271.                         wd,
  272.                         NULL,
  273.                         wnd,
  274.                         NULL,
  275.                         0);
  276. #ifdef INCLUDE_SHADOWS
  277.             AddAttribute(mwnd, SHADOW);
  278. #endif
  279.             if (mnu->Selections[0].SelectionTitle != NULL)    {
  280.                 SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
  281.                 SendMessage(mwnd, SETFOCUS, TRUE, 0);
  282.             }
  283.             else
  284.                 SendMessage(wnd, PAINT, 0, 0);
  285.             Selecting = FALSE;
  286.             break;
  287.         case BORDER:
  288.             return TRUE;
  289.         case INSIDE_WINDOW:
  290.             return InsideRect(p1, p2, WindowRect(wnd));
  291.         case CLOSE_POPDOWN:
  292.             if (casc > 0)
  293.                 SendMessage(Cascaders[--casc], CLOSE_WINDOW, p1, 0);
  294.             else     {
  295.                 if ((int)p1)
  296.                     PostMessage(wnd, KEYBOARD, ESC, 0);
  297.                 mwnd = NULLWND;
  298.                 ActiveMenuBar->ActiveSelection = -1;
  299.             }
  300.             return TRUE;
  301.         case CLOSE_WINDOW:
  302.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  303.             if (GetText(wnd) != NULL)    {
  304.                 free(GetText(wnd));
  305.                 GetText(wnd) = NULL;
  306.             }
  307.             mctr = 0;
  308.             ActiveMenuBar->ActiveSelection = -1;
  309.             MenuBarWnd = NULL;
  310.             ActiveMenu = NULL;
  311.             ActiveMenuBar = NULL;
  312.             return rtn;
  313.         default:
  314.             break;
  315.     }
  316.     return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  317. }
  318.  
  319. static void reset_menubar(WINDOW wnd)
  320. {
  321.     if ((GetText(wnd) = realloc(GetText(wnd), SCREENWIDTH+5)) != NULL)    {
  322.         memset(GetText(wnd), ' ', SCREENWIDTH);
  323.         *(GetText(wnd)+SCREENWIDTH-
  324.             (TestAttribute(GetParent(wnd), HASBORDER) ? 2 : 0)) = '\0';
  325.     }
  326. }
  327.  
  328. static int TestGlobalKeys(WINDOW wnd, PARAM p1, PARAM p2)
  329. {
  330.     switch ((int)p1)    {
  331.         case F10:
  332.             if (MenuBarWnd != NULLWND)
  333.                 SendMessage(MenuBarWnd, SETFOCUS, TRUE, 0);
  334.             return TRUE;
  335.         case ALT_F6:
  336.             if (GetClass(inFocus) == POPDOWNMENU)
  337.                 return TRUE;
  338.             SetNextFocus(inFocus);
  339.             SkipSystemWindows(FALSE);
  340.             return TRUE;
  341. #ifdef INCLUDE_SYSTEM_MENUS
  342.         case ALT_HYPHEN:
  343.             if (GetClass(inFocus) == POPDOWNMENU)
  344.                 SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
  345.             if (GetClass(GetParent(inFocus)) == APPLICATION)
  346.                 BuildSystemMenu(GetParent(inFocus));
  347.             return TRUE;
  348.         case ' ':
  349.             if ((int)p2 & ALTKEY)    {
  350.                 if (GetClass(inFocus) == POPDOWNMENU)
  351.                     SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
  352.                 if (GetClass(inFocus) != MENUBAR &&
  353.                         TestAttribute(inFocus, HASTITLEBAR) &&
  354.                             TestAttribute(inFocus, CONTROLBOX))
  355.                     BuildSystemMenu(inFocus);
  356.                 return TRUE;
  357.             }
  358.             break;
  359. #endif
  360.         case CTRL_F4:
  361.             if (GetClass(inFocus) != MENUBAR)
  362. #ifdef INCLUDE_STATUSBAR
  363.                 if (GetClass(inFocus) != STATUSBAR)
  364. #endif
  365.                     if (GetClass(inFocus) != APPLICATION)    {
  366.                         SendMessage(inFocus, CLOSE_WINDOW, 0, 0);
  367.                         SkipSystemWindows(FALSE);
  368.                     }
  369.             break;
  370.         case ALT_F4:
  371.             PostMessage(GetParent(wnd), CLOSE_WINDOW, 0, 0);
  372.             break;
  373.         default:
  374.             break;
  375.     }
  376.     return FALSE;
  377. }
  378.  
  379. int BarSelection(int mx)
  380. {
  381.     int i;
  382.     for (i = 0; i < mctr; i++)
  383.         if (mx >= menu[i].x1-4*i &&
  384.                 mx <= menu[i].x2-4*i-5)
  385.             break;
  386.     return i;
  387. }
  388.  
  389.  
  390.